//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//
//------------------------------------------------------------------------------
//
//  File:  intr.h
//
//  This file contains Littleton board specific interrupt code.
//
#include <bsp.h>

#include <args.h>

#include <xllp_gpio_plat.h>

extern BSP_ARGS *g_pBSPArgs;


#define INTMSK_RESERVED_BITS          0xFFFF1100
#define INTSETCLR_RESERVED_BITS       0xFFFF1100

static volatile XLLP_GPIO_T    *g_pGPIORegs = NULL;

#define NUM_GPIO					(XLLP_GPIO_ID_MAX+1)


UINT32   g_GPIOEdgeDetect[NUM_GPIO] = 
{
	// Specific for Monahans P.
	// TODO: Figure out the map for Monahans L/LV
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 0-7
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 8-15		GP15 for touch(AC97)
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 16-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 32-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 48-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 64-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 72-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 80-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 88-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_RISE, GPIO_MASK, // 96-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 104-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // 112-
	GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, GPIO_MASK, // -127

};

//------------------------------------------------------------------------------
//
//  Function:  BSPIntrInit
//
BOOL BSPIntrInit()
{
    volatile XLLP_INTC_T *pIntrRegs = NULL;
	unsigned int touch_device = g_pBSPArgs->DefaultTouchDriver;

    OALMSG(OAL_INTR&&OAL_FUNC, (L"+BSPIntrInit\r\n"));

    pIntrRegs   = (volatile XLLP_INTC_T *) OALPAtoVA(MONAHANS_BASE_REG_PA_INTC, FALSE);
    g_pGPIORegs = (volatile XLLP_GPIO_T *) OALPAtoVA(MONAHANS_BASE_REG_PA_GPIO, FALSE);


    // TO DO: Make static mappings as less as possible.
    // CAUTION: Need to keep sync with SYSINTR def in bsp_cfg.h !
    // There are also some dummy mappings here. 
    // Set up static interrupt mappings

    //OHCI MDD read the SYSINTR from the register, so we can't use the dynamic SYSINTR
    OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBOHCI);

    //TODO: Reserve SYSINTR_TOUCH, GPIO28 should be safe on Littleton
    OALIntrStaticTranslate(SYSINTR_TOUCH, 			IRQ_GPIO_SHARE(28));
    OALIntrStaticTranslate(SYSINTR_TOUCH_CHANGED,	XLLP_INTC_S_OST_M1);
   
    //USB client load the SYSINTR from registor and share it with OTG, so we use the static mapping
    OALIntrStaticTranslate(SYSINTR_USBFN, 			IRQ_USBFN);

    //RIL will also use the SYSINTR_FFUART
    OALIntrStaticTranslate(SYSINTR_FFUART,   IRQ_FFUART);

    OALIntrStaticTranslate(SYSINTR_SSP4, 			IRQ_SSP4);

    //Example to use GPIO IRQ:
    //OALIntrStaticTranslate(SYSINTR_DBG_ETHERNET, IRQ_GPIO_SHARE(XLLP_GPIO_DEBUG_ETH_INT));	


//    OALIntrStaticTranslate(SYSINTR_SMSC91C111, IRQ_GPIO_SHARE(XLLP_GPIO_DEBUG_ETH_INT));

//    OALIntrStaticTranslate(SYSINTR_PWRBUTTON, XLLP_INTC_S_EXT1); 		// INTC_S_EXT1 should be SW6 on the MB


    OALMSG(OAL_INTR&&OAL_FUNC, (L"-BSPIntrInit\r\n"));

    return TRUE;
}

//------------------------------------------------------------------------------

BOOL BSPIntrRequestIrqs(DEVICE_LOCATION *pDevLoc, UINT32 *pCount, UINT32 *pIrqs)
{
    BOOL rc = FALSE;

    OALMSG(OAL_INTR&&OAL_FUNC, (
        L"+BSPIntrRequestIrq(0x%08x->%d/%d/0x%08x/%d, 0x%08x, 0x%08x)\r\n", 
        pDevLoc, pDevLoc->IfcType, pDevLoc->BusNumber, pDevLoc->LogicalLoc,
        pDevLoc->Pin, pCount, pIrqs
    ));

    // Check for input params
    if (pIrqs == NULL || pCount == NULL || *pCount < 1) goto Done;
/*
    switch (pDevLoc->IfcType) {
    case Internal:
        switch ((ULONG)pDevLoc->LogicalLoc) {
        case (LITTLETON_BASE_REG_PA_SMSC_ETHERNET + 0x300):
            pIrqs[0] = IRQ_GPIO_SHARE(XLLP_GPIO_DEBUG_ETH_INT);	
            *pCount = 1;
            rc = TRUE;
            break;
        }
        break;
    }
*/
Done:
    OALMSG(OAL_INTR&&OAL_FUNC, (L"-BSPIntrRequestIrq(rc = %d)\r\n", rc));
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function:  BSPIntrEnableIrq
//
//  This function is called from OALIntrEnableIrq to enable interrupt on
//  secondary interrupt controller.
//
UINT32 BSPIntrEnableIrq(UINT32 irq)
{
    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+void for Zy BSPIntrEnableIrq(%d)\r\n", irq));

    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrEnableIrq(irq = %d)\r\n", irq));
    return irq;
}

//------------------------------------------------------------------------------
//
//  Function:  BSPIntrDisableIrq
//
//  This function is called from OALIntrDisableIrq to disable interrupt on
//  secondary interrupt controller.
//
UINT32 BSPIntrDisableIrq(UINT32 irq)
{
    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+void for Zy BSPIntrDisableIrq(%d)\r\n", irq));

    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrDisableIrq(irq = %d\r\n", irq));
    return irq;
}

//------------------------------------------------------------------------------
//
//  Function:  BSPIntrDoneIrq
//
//  This function is called from OALIntrDoneIrq to finish interrupt on
//  secondary interrupt controller.
//
UINT32 BSPIntrDoneIrq(UINT32 irq)
{

    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+void for Zy BSPIntrDoneIrq(%d)\r\n", irq));

    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrDoneIrq(irq = %d)\r\n", irq));
    return irq;
}


//------------------------------------------------------------------------------
//
//  Function:  BSPIntrActiveIrq
//
//  This function is called from interrupt handler to give BSP chance to 
//  translate IRQ in case of secondary interrupt controller.
//
UINT32 BSPIntrActiveIrq(UINT32 irq)
{
    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+void for Zy BSPIntrActiveIrq(%d)\r\n", irq));

    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrActiveIrq(%d)\r\n", irq));
    return irq;
}


//------------------------------------------------------------------------------
//
//  Function:  FPGAInterruptHandler
//
//  This function is called from the BSP ISR to handle an FPGA interrupt.
//
static UINT32 FPGAInterruptHandler(UINT32 irq)
{
    return(irq);
}

//------------------------------------------------------------------------------

